package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.constant.EsNormalConstant;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.elasticsearch.model.PaasFormSubDataEsModel;
import com.xbongbong.paas.elasticsearch.pojo.dto.AssociationListDataDTO;
import com.xbongbong.paas.elasticsearch.pojo.dto.SearchDataInConditionDTO;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.feign.WorkOrderV2ExplainFeignClient;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.help.FormDataListSearchHelp;
import com.xbongbong.paas.help.PaasFormHelp;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.linkdata.LinkDataExplainVO;
import com.xbongbong.paas.pojo.linkdata.dto.LinkDataExplainDTO;
import com.xbongbong.paas.pojo.vo.AssociationListDataVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.pojo.vo.UserFormPermissionVO;
import com.xbongbong.paas.service.AssociationService;
import com.xbongbong.paas.service.UserService;
import com.xbongbong.paas.service.WorkReportSetService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.pojo.PermissionTermsPojo;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.explain.FormDataListFormExplainHandleName;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.AddProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.ViewProPermissionAliasEnum;
import com.xbongbong.pro.formdata.pojo.vo.FormDataVO;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetVisibleRange;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.ListOptionEnum;
import com.xbongbong.saas.enums.ListOptionTabEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.WorkOrderNodeStatusEnum;
import com.xbongbong.saas.enums.WorkOrderTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ExpenseEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.help.SaasListHelp;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2019/9/3 11:08
 * @since v1.0
 */
@Service
public class AssociationServiceImpl implements AssociationService {

    private static final Logger LOG = LoggerFactory.getLogger(AssociationServiceImpl.class);

    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private FormDataListSearchHelp formDataListSearchHelp;
    @Resource
    private SaasListHelp saasListHelp;
    @Resource
    private PaasFormHelp paasFormHelp;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private UserService userService;
    @Resource
    private FormDataListFormExplainHandleName formDataListFormExplainHandleName;
    @Resource
    private WorkReportSetService workReportSetService;
    @Resource
    private ProductService productService;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasFormSubDataEsModel paasFormSubDataEsModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private WorkOrderV2ExplainFeignClient workOrderV2ComboFeignClient;

    @Override
    public AssociationListDataVO associationListDataList(AssociationListDataDTO associationListDataDTO) throws XbbException {
        AssociationListDataVO associationListDataVO = new AssociationListDataVO();
        try {
            String corpid = associationListDataDTO.getCorpid();
            FormDataListDTO formDataListDTO = new FormDataListDTO();
            BeanUtil.copyProperties(associationListDataDTO, formDataListDTO);
            //解释获取以及处理
            PaasFormEntityExt form = new PaasFormEntityExt();
            LinkListPojo linkListPojo = associationListDataDTO.getLinkList();
            Integer businessType = linkListPojo.getLinkBusinessType();

            List<FieldAttrEntity> explainList;
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(linkListPojo.getLinkFormId(), corpid);
                if (workOrderFormEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderFormEntity, form);
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(linkListPojo.getLinkFormId(), corpid);
                if(workOrderExplainEntityExt == null ) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                List<FieldAttrEntity> fieldList = JSON.parseArray(workOrderExplainEntityExt.getExplains(), FieldAttrEntity.class);
                HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                BeanUtil.copyProperties(formDataListDTO, handlerExplainDTO, false);
                form.setSaasMark(SaasMarkEnum.SAAS.getCode());
                form.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
                form.setSummaryList(form.getSummary());
                form.setLabelsList(form.getLabels());
                handlerExplainDTO.setExplainList(fieldList);
                handlerExplainDTO.setPaasFormEntityExt(form);
                HandlerExplainVO handlerExplainVO = formDataListFormExplainHandleName.handleExplain(handlerExplainDTO);
                if(handlerExplainVO == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                explainList = handlerExplainVO.getHeadList();
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(JSON.toJSONString(explainList), null);
                formDataListDTO.setExplainMap(explainMap);
            } else {
                form = paasFormModel.getByKey(linkListPojo.getLinkFormId(), corpid);
                if (form == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                HandleExplainPojo handleExplainPojo = formDataListSearchHelp.handlExplains(formDataListDTO,form);
                explainList = handleExplainPojo.getExplainList();

            }


            BoolQueryBuilder boolQueryBuilder = boolQuery();
            // 设置条件
            EsUtil.getTermQuery(boolQueryBuilder, associationListDataDTO, true);

            boolQueryBuilder.filter(termQuery("formId", linkListPojo.getLinkFormId()));

            String linkListAttr = linkListPojo.getAttr();
            boolean isSpecialSubForm = true;
            List<String> attrList = ExplainUtil.getAttrByPoint(linkListAttr);
            if (!attrList.isEmpty()) {
                isSpecialSubForm = EsHelper.isSpecialSubForm(attrList.get(0), businessType);
            }
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, linkListPojo.getLinkBusinessType(), linkListPojo.getLinkSaasMark());
            if (!isSpecialSubForm) {
                IndexTypeEnum subFormIndexTypeEnum = IndexTypeEnum.getSubEnum(indexTypeEnum);
                linkListAttr = attrList.get(1);
                BoolQueryBuilder subFormBoolQueryBuilder = boolQuery();
                subFormBoolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
                subFormBoolQueryBuilder.filter(termQuery("formId", linkListPojo.getLinkFormId()));
                subFormBoolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
                if (Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(), associationListDataDTO.getBusinessType())) {
                    ProductEntityExt productEntityExt = productModel.getByKey(associationListDataDTO.getDataId(), corpid);
                    JSONObject jsonObject = productEntityExt.getData();
                    Long productId = jsonObject.getLong(ProductEnum.PARENT_ID.getAttr());
                    if (Objects.equals(0L, productId)) {
                        List<PaasFormDataEntityExt> dataList = productService.getDataByParentId(corpid, associationListDataDTO.getDataId());
                        if (CollectionsUtil.isNotEmpty(dataList)) {
                            Set<Long> childProductIdList = new HashSet<>();
                            dataList.forEach(item->{
                                childProductIdList.add(item.getDataId());
                            });
                            subFormBoolQueryBuilder.filter(termsQuery("data." + linkListAttr, childProductIdList));
                            Set<Long> parentIdList = getParentIdList(subFormBoolQueryBuilder, subFormIndexTypeEnum);

                            boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), parentIdList));
                        }
                    } else {
                        subFormBoolQueryBuilder.filter(termQuery("data." + linkListAttr+".keyword", associationListDataDTO.getDataId()));
                        Set<Long> parentIdList = getParentIdList(subFormBoolQueryBuilder, subFormIndexTypeEnum);
                        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), parentIdList));
                    }
                } else if (Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(), linkListPojo.getLinkBusinessType())) {
                    // 关联产品表，搜索父产品，避免出现子产品
                    subFormBoolQueryBuilder.filter(termQuery("data." + linkListAttr+".keyword", associationListDataDTO.getDataId()));
                    Set<Long> parentIdList = getParentIdList(subFormBoolQueryBuilder, subFormIndexTypeEnum);
                    boolQueryBuilder.filter(termQuery("data." + ProductEnum.PARENT_ID.getAttr(), 0));
                    boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), parentIdList));
                } else {
                    subFormBoolQueryBuilder.filter(termQuery("data." + linkListAttr+".keyword", associationListDataDTO.getDataId()));
                    Set<Long> parentIdList = getParentIdList(subFormBoolQueryBuilder, subFormIndexTypeEnum);
                    boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), parentIdList));
                }
            } else {
                if (Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(), associationListDataDTO.getBusinessType())) {
                    List<PaasFormDataEntityExt> dataList = productService.getDataByParentId(corpid, associationListDataDTO.getDataId());
                    if (Objects.isNull(dataList) || dataList.isEmpty()) {
                        boolQueryBuilder.filter(termQuery("data." + linkListAttr+".keyword", associationListDataDTO.getDataId()));
                    } else {
                        BoolQueryBuilder subData = boolQuery();
                        for (PaasFormDataEntityExt item : dataList) {
                            subData.should(termQuery("data." + linkListAttr + ".keyword", item.getDataId()));
                        }
                        subData.minimumShouldMatch(EsNormalConstant.MINI_MUM_SHOULD_MATCH);
                        boolQueryBuilder.filter(subData);
                    }
                } else if (Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(), linkListPojo.getLinkBusinessType())) {
                    // 关联产品表，搜索父产品，避免出现子产品
                    boolQueryBuilder.filter(termQuery("data." + ProductEnum.PARENT_ID.getAttr(), 0));
                    boolQueryBuilder.filter(termQuery("data." + linkListAttr+".keyword", associationListDataDTO.getDataId()));
                } else {
                    boolQueryBuilder.filter(termQuery("data." + linkListAttr +".keyword", associationListDataDTO.getDataId()));
                }
            }
            // 获取权限内的数据
            SearchDataInConditionDTO searchDataInConditionDTO = new SearchDataInConditionDTO();
            BeanUtil.copyProperties(associationListDataDTO, searchDataInConditionDTO);
            searchDataInConditionDTO.setBusinessType(businessType);
            searchDataInConditionDTO.setSubBusinessType(businessType);
            searchDataInConditionDTO.setSaasMark(linkListPojo.getLinkSaasMark());
            searchDataInConditionDTO.setFormId(linkListPojo.getLinkFormId());
            searchDataInConditionDTO.setDefaultGroup(1);
            searchDataInConditionDTO.setListGroupId(ListGroupEnum.ALL.getCode().longValue());
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                //工单正常列表数据
                ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
                conditionsEntityExt.setAttr(FieldTypeEnum.WORK_ORDER_ROB.getAlias());
                conditionsEntityExt.setFieldType(FieldTypeEnum.WORK_ORDER_ROB.getType());
                conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
                conditionsEntityExt.setValue(Collections.singletonList(WorkOrderTypeEnum.NORMAL.getCode()));
                searchDataInConditionDTO.getConditionsList().add(conditionsEntityExt);
            }
            saasListHelp.packageSearchDataCondition(searchDataInConditionDTO);

            if (Objects.equals(XbbRefTypeEnum.QUOTATION.getCode(), businessType)) {
                // bug-id =20370
                List<ConditionsEntityExt> conditionList = searchDataInConditionDTO.getConditionsList();
                if (CollectionsUtil.isNotEmpty(conditionList)) {
                    Iterator<ConditionsEntityExt> iterator = conditionList.iterator();
                    while (iterator.hasNext()) {
                        ConditionsEntityExt conditionsEntityExt = iterator.next();
                        if (Objects.equals(QuotationEnum.IS_NEW.getAttr(), conditionsEntityExt.getAttr())) {
                            iterator.remove();
                            continue;
                        }
                    }
                }
            }

            EsUtil.parseCondition(boolQueryBuilder,searchDataInConditionDTO.getConditionsList(),"",searchDataInConditionDTO.getCorpid(),searchDataInConditionDTO.getBusinessType());

            BoolQueryBuilder boolQuery = boolQuery();
            EsUtil.parseShouldCondition(boolQuery,searchDataInConditionDTO.getShouldConditionsList(),"",searchDataInConditionDTO.getCorpid(),searchDataInConditionDTO.getBusinessType());
            boolQueryBuilder.filter(boolQuery);
            // 共享权限
            EsUtil.parseSharePermissionCondition(boolQueryBuilder, searchDataInConditionDTO.getSharePermission(), searchDataInConditionDTO.getCorpid(), searchDataInConditionDTO.getBusinessType(), formDataListDTO.getFromThrough());
            //分页
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
            sourceBuilder.query(boolQueryBuilder);
            // 排序
            sourceBuilder.sort(new FieldSortBuilder(FieldTypeEnum.UPDATETIME.getAlias()).order(SortOrder.DESC));
            associationListDataDTO.setSourceBuilder(sourceBuilder);
            // 字段
            Set<String> fieldSet = new HashSet<>();

            List<SummaryDataPoJo> list = JSON.parseArray(form.getSummary(), SummaryDataPoJo.class);
            if (Objects.nonNull(list)) {
                list.forEach(item->{
                    // TODO 摘要没有支持子表单
                    if (!ExplainUtil.isSubForm(item.getFieldType())) {
                        fieldSet.add(item.getAttr());
                    }
                });
            }
            associationListDataVO = paasFormDataEsModel.associationListDataList(associationListDataDTO, indexTypeEnum);
            List<PaasFormDataEntityExt> paasFormDataEntityExtList = new ArrayList<>();
            for(WorkOrderEntityExt entity : associationListDataVO.getResultList()){
                PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
                BeanUtil.copyProperties(entity,paasFormDataEntityExt);
                paasFormDataEntityExt.setTagData(new JSONObject());
                paasFormDataEntityExtList.add(paasFormDataEntityExt);
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)
                        && Objects.equals(associationListDataDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                    JSONObject data = entity.getData();
                    if (Objects.isNull(data)) {
                        continue;
                    }
                    data.put(FieldTypeEnum.CLOSETIME.getAlias(),entity.getCloseTime());
                    data.put(FieldTypeEnum.ENDTIME.getAlias(),entity.getEndTime());
                    data.put(FieldTypeEnum.WORK_ORDER_STATUS.getAlias(), WorkOrderNodeStatusEnum.getByCode(entity.getStatus()).getName());
                }
            }
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER_V2.getCode())) {
                List<FormDataVO> formDataList = new ArrayList<>();
                paasFormDataEntityExtList.forEach(item->{
                    FormDataVO formDataVO = new FormDataVO();
                    formDataVO.setData(item.getData());
                    formDataList.add(formDataVO);
                });
                LinkDataExplainDTO linkDataExplainDTO = new LinkDataExplainDTO(explainList, formDataList, corpid, businessType);
                XbbResponse<LinkDataExplainVO> xbbResponse = workOrderV2ComboFeignClient.getExplain(linkDataExplainDTO, LocaleContextHolder.getLocale().toString());
                if (xbbResponse.isSuccess()) {
                    explainList = xbbResponse.getResult().getExplainList();
                }
            }

            formDataListDTO.setSaasMark(linkListPojo.getLinkSaasMark());
            formDataListDTO.setBusinessType(businessType);
            formDataListDTO.setSubBusinessType(businessType);
            PaasFormDataEsListVO formDataListVO = new PaasFormDataEsListVO();
            BeanUtil.copyProperties(associationListDataVO, formDataListVO);
            formDataListVO.setPaasFormDataESList(paasFormDataEntityExtList);
            formDataListVO.setHeadList(explainList);
            formDataListVO.setForm(form);
            Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
            explainList.forEach(item->{
                explainMap.put(item.getAttr(), item);
            });
            formDataListVO.setExplainMap(explainMap);
            if (PlatFormEnum.WEB.getValue().equals(associationListDataDTO.getPlatform())) {
                formDataListSearchHelp.webDataAnalysis(formDataListDTO,formDataListVO);
            } else if (PlatFormEnum.DINGTALK.getValue().equals(formDataListDTO.getPlatform())) {
                formDataListVO = formDataListSearchHelp.appDataAnalysis(formDataListDTO, formDataListVO);
            }


            /* ==================== 按钮权限 ==================== */
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), linkListPojo.getLinkSaasMark())) {
                List<ButtonPojo> topPermissionList = new ArrayList<>();
                if (Objects.equals(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), businessType)
                        || Objects.equals(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), businessType)
                        ||Objects.equals(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), businessType) ) {
                    UserEntity userEntity = new UserEntity();
                    BeanUtil.copyProperties(associationListDataDTO.getLoginUser(), userEntity);
                    WorkReportSetVisibleRange workReportSetVisibleRange = workReportSetService.getVisibleRange(userEntity);
                    if (workReportSetVisibleRange.getDayEnable()
                            || workReportSetVisibleRange.getMonthEnable()
                            || workReportSetVisibleRange.getWeekEnable()) {
                        ButtonPojo buttonPojo = new ButtonPojo();
                        buttonPojo.setAttr(SaasButtonEnum.ADD.getAttr());
                        buttonPojo.setValue(SaasButtonEnum.ADD.getValue());
                        buttonPojo.setType(SaasButtonEnum.ADD.getType());
                        topPermissionList.add(buttonPojo);
                    }
                } else {
                    AddProPermissionAliasEnum addProPermissionAliasEnum = AddProPermissionAliasEnum.getByCode(businessType);
                    if (Objects.nonNull(addProPermissionAliasEnum) && associationListDataDTO.getLoginUser().getPermSet().contains(addProPermissionAliasEnum.getAlias())) {
                        ButtonPojo buttonPojo = new ButtonPojo();
                        buttonPojo.setAttr(SaasButtonEnum.ADD.getAttr());
                        buttonPojo.setValue(SaasButtonEnum.ADD.getValue());
                        buttonPojo.setType(SaasButtonEnum.ADD.getType());
                        topPermissionList.add(buttonPojo);
                    }
                }

                 associationListDataVO.setTopPermissions(topPermissionList);
            } else {
                associationListDataVO.setTopPermissions(paasFormHelp.getAddPermission(linkListPojo, associationListDataDTO.getLoginUser()));
            }
            BeanUtil.copyProperties(formDataListVO, associationListDataVO);
            List<FieldAttrEntity> headList = associationListDataVO.getHeadList();
            Iterator<FieldAttrEntity> iterator = headList.iterator();
            while (iterator.hasNext()) {
                FieldAttrEntity fieldAttrEntity = iterator.next();
                Integer fieldType = fieldAttrEntity.getFieldType();
                FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
                // 按钮操作的，都去掉
                if (Objects.equals(fieldTypeEnum.getEsalias(), FieldTypeEnum.OPTION.getEsalias())) {
                    iterator.remove();
                    continue;
                }
                if (ExplainUtil.isSubForm(fieldType)) {
                    // 先去掉子表单
                    iterator.remove();
                    continue;
                }
                if (!fieldSet.isEmpty() && !fieldSet.contains(fieldAttrEntity.getAttr())) {
                    iterator.remove();
                    continue;
                }
                //关联列表不支持富文本
                if (Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.RICH_TEXT.getType())) {
                    iterator.remove();
                    continue;
                }
            }

            Boolean viewPermission = false;
            UserVO userVO = associationListDataDTO.getLoginUser();
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), linkListPojo.getLinkSaasMark())) {
                ViewProPermissionAliasEnum viewProPermissionAliasEnum = ViewProPermissionAliasEnum.getByCode(businessType);
                if (Objects.nonNull(viewProPermissionAliasEnum) && userVO.getPermSet().contains(viewProPermissionAliasEnum.getAlias())) {
                    viewPermission = true;
                }
            } else {
                UserFormPermissionVO userFormPermissionVO = userService.getUserFormPermissionInternal(corpid,
                        userVO.getUserId(), linkListPojo.getLinkAppId(), linkListPojo.getLinkMenuId());
                PermissionTermsPojo permissionTerms = userFormPermissionVO.getFormPermission().getPermission();
                viewPermission = permissionTerms.getRead() == 1;
            }
            viewPermission = viewPermission && paasFormModel.getPermission(JSON.parseArray(form.getPermission(), OptionalRangeEntity.class), userVO);
            List<PaasFormDataEntityExt> paasFormDataList = formDataListVO.getPaasFormDataESList();
            if (userVO.isAdminOrBoss() || viewPermission) {
                // 添加一行操作列
                FieldAttrEntity fieldOption = new FieldAttrEntity();
                fieldOption.setAttr(ListOptionEnum.OPTION.getAttr());
                fieldOption.setAttrName(ListOptionEnum.OPTION.getAttrName());
                fieldOption.setFieldType(FieldTypeEnum.OPTION.getType());
                headList.add(0, fieldOption);
                for (PaasFormDataEntityExt item : paasFormDataList) {
                    JSONObject data = item.getData();
                    List<ButtonPojo> optionList = new ArrayList<>();
                    optionList.add(new ButtonPojo(ListOptionTabEnum.VIEW));
                    JSONObject option = new JSONObject();
                    option.put("value", optionList);
                    data.put(ListOptionEnum.OPTION.getAttr(), option);
                }
            } else {
                paasFormDataList = new ArrayList<>();
            }
            // 删除掉工单的产品，耗时、阶段状态、阶段名称、阶段；
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                Iterator<FieldAttrEntity> explainIterator = headList.iterator();
                while (explainIterator.hasNext()) {
                    FieldAttrEntity fieldAttrEntity = explainIterator.next();
                    String attr = fieldAttrEntity.getAttr();
                    if (Objects.equals(WorkOrderEnum.SPARE_PARTS.getAttr(), attr)
                            || Objects.equals(WorkOrderEnum.TIME_OUT.getAttr(), attr)
                            || Objects.equals(WorkOrderEnum.NODE_STATUS.getAttr(), attr)
                            || Objects.equals(WorkOrderEnum.STAGE_NAME.getAttr(), attr)
                            || Objects.equals(WorkOrderEnum.STAGE.getAttr(), attr)
                    ) {
                        explainIterator.remove();
                        continue;
                    }
                }
            }

            if (Objects.equals(XbbRefTypeEnum.EXPENSE.getCode(), businessType)) {
                Iterator<FieldAttrEntity> explainIterator = headList.iterator();
                while (explainIterator.hasNext()) {
                    FieldAttrEntity fieldAttrEntity = explainIterator.next();
                    String attr = fieldAttrEntity.getAttr();
//                    if ( Objects.equals(ExpenseEnum.EXPENSE_CODE.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.REIMBURSEMENT_FORM_ID.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.REIMBURSEMENT_FORM_CODE.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.EXPENSE_TYPE.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.AMOUNT.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.CONSUME_TIME.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.FORM_USER_NAME.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.PROJECT_NAME.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.PROJECT_CODE.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.BUSINESS_TYPE.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.BUSINESS_ID.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.BUSINESS_NAME.getAttr(), attr) ||
//                            Objects.equals(ExpenseEnum.APPORTIONED_AMOUNT.getAttr(), attr)
//                    ) {
                    if ( Objects.equals(ListOptionEnum.OPTION.getAttr(), attr) ||
                            Objects.equals(ExpenseEnum.REIMBURSEMENT_FORM_ID.getAttr(), attr)
                    ) {
                        explainIterator.remove();
                        continue;
                    }
                }
            }

            associationListDataVO.setHeadList(headList);
            associationListDataVO.setResultList(null);
            associationListDataVO.setPaasFormDataESList(paasFormDataList);
        } catch (Exception e) {
            LOG.error("formData.associationListDataList获取关联列表的数据出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return associationListDataVO;
    }

    @Override
    public void updateAssociation(String corpid, Long formId, Integer businessType) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("linkFormId", String.valueOf(formId));
        param.put("linkBusinessType", String.valueOf(businessType));
        param.put("associationListFlag", 1);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<PaasFormEntityExt> formList = paasFormModel.findEntitys(param);
        if (CollectionsUtil.isNotEmpty(formList)) {
            List<PaasFormEntity> updateList = new ArrayList<>();
            formList.forEach(item->{
                List<LinkListPojo> linkList = JSON.parseArray(item.getAssociationList(), LinkListPojo.class);
                Iterator<LinkListPojo> iterator = linkList.iterator();
                while (iterator.hasNext()) {
                    LinkListPojo linkListPojo = iterator.next();
                    if (Objects.equals(linkListPojo.getLinkFormId(), formId)) {
                        iterator.remove();
                        continue;
                    }
                }
                PaasFormEntity updateForm = new PaasFormEntity();
                updateForm.setId(item.getId());
                updateForm.setAssociationList(JSON.toJSONString(linkList));
                long now = DateUtil.getInt();
                updateForm.setUpdateTime(now);
                updateList.add(updateForm);
            });
            if (CollectionsUtil.isNotEmpty(updateList)) {
                paasFormModel.updateBatch(updateList, corpid);
            }
        }
        param.clear();
        param.put("corpid", corpid);
        param.put("linkFormId", String.valueOf(formId));
        param.put("linkBusinessType", String.valueOf(businessType));
        param.put("associationListFlag", 1);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<WorkOrderFormEntity> workOrderFormList = workOrderFormModel.findEntitys(param);
        if (CollectionsUtil.isNotEmpty(workOrderFormList)) {
            List<WorkOrderFormEntity> updateList = new ArrayList<>();
            workOrderFormList.forEach(item->{
                List<LinkListPojo> linkList = JSON.parseArray(item.getAssociationList(), LinkListPojo.class);
                Iterator<LinkListPojo> iterator = linkList.iterator();
                while (iterator.hasNext()) {
                    LinkListPojo linkListPojo = iterator.next();
                    if (Objects.equals(linkListPojo.getLinkFormId(), formId)) {
                        iterator.remove();
                        continue;
                    }
                }
                WorkOrderFormEntity updateForm = new WorkOrderFormEntity();
                updateForm.setId(item.getId());
                updateForm.setAssociationList(JSON.toJSONString(linkList));
                long now = DateUtil.getInt();
                updateForm.setUpdateTime(now);
                updateList.add(updateForm);
            });
            if (CollectionsUtil.isNotEmpty(updateList)) {
                workOrderFormModel.updateBatch(updateList, corpid);
            }
        }
    }

    /**
     * 根据子表单的关联数据id获取主数据id
     * @param subFormBoolQueryBuilder
     * @param subFormIndexTypeEnum
     * @return
     * @throws XbbException
     */
    private Set<Long> getParentIdList(BoolQueryBuilder subFormBoolQueryBuilder, IndexTypeEnum subFormIndexTypeEnum) throws XbbException{
        Set<Long> idSet = new HashSet<>();
        List<PaasFormSubDataEntity> subDataList = paasFormSubDataEsModel.getSubDataList(subFormBoolQueryBuilder, subFormIndexTypeEnum, Arrays.asList(FieldTypeEnum.DATAID.getAlias()), 1, PaasConstant.ES_MAX_PAGE_SIZE, PaasFormSubDataEntity.class);
        if (CollectionsUtil.isNotEmpty(subDataList)) {
            subDataList.forEach(item->{
                idSet.add(item.getDataId());
            });
        }
        return idSet;
    }
}
